package cn.lcsjsxy.yxc.renerics;

import org.junit.jupiter.api.Test;

import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * 1.泛型在继承方面的体现
 *
 * 2.通配符的使用
 */
public class GenericTest3 {
    /*
     * 1.泛型在继承方面的体现
     *
     * 虽然类A是类B的父类，但是G<A> 和 G<B>二者不具备父类关系，二者是并列关系
     *
     * 补充：类A是类B的父类，A<G> 是 B<G>的父类
     */
    @Test
    public void test1(){
        Object obj=null;
        String str=null;
        obj=str;

        Object[] arr1=null;
        String[] arr2=null;
        arr1=arr2;

        List<Object> list1=null;
        List<String> list2=null;
        //此时的list1和list2的类型不具有子父类关系
        //编译不通过
//        list1=list2l;
        /*
        * 反证法：
        * 假如list1=list2；
        * list1.add(123);  导致混入非String的数据，出错
        * */
        show1(list1);
        show2(list2);
    }

    public void show1(List<Object> list){

    }

    public void show2(List<String> list){

    }

    @Test
    public void test2(){
        List<String> list1=null;
        ArrayList<String> list2=null;
        AbstractList<String> list3=null;
        list1=list2;
        list3=list2;
    }

    /*
    * 2.通配符的使用
    *   通配符：？
    *
    * 类A是类B的父类，G<A>和G<B>是没有关系的，二者的父类是:G<?>
    * */
    @Test
    public void test3(){
        List<Object> list1=null;
        List<String> list2=null;

        List<?> list3=null;

        list3=list1;
        list3=list2;

        //
        List<String> list4=new ArrayList<>();
        list4.add("AA");
        list4.add("BB");
        list4.add("CC");
        list3=list4;
        //添加：对于List<?>就不能向其内部添加数据
//        list3.add(123);
//        list3.add("AA");
        //除了添加null之外
        list3.add(null);

        //获取（读取）：允许读取数据，读取的数据类型为Object
        Object o=list3.get(0);
        System.out.println(o);
    }

    public void print(List<?> list){
        Iterator<?> iterator=list.iterator();
        while (iterator.hasNext()){
            Object obj=iterator.next();
            System.out.println(obj);
        }
    }

    /*
    * 3.有限制条件的通配符的使用。
    *   ? extends A: G<? extends A>可以作为G<A>和G<B>的父类的，其中B是A的子类
    *
    *   ? super A: G<? super A>可以作为G<A>和G<B>的父类的，其中B是A的父类
    * */
    @Test
    public void test4(){
        List<? extends Person> list1=null;
        List<? super Person> list2=null;
        List<Student> list3=new ArrayList<>();
        List<Person> list4=new ArrayList<>();
        List<Object> list5=new ArrayList<>();

        list1=list3;
        list1=list4;
//        list1=list5;

//        list2=list3;
        list2=list4;
        list2=list5;

        //读取数据：
        list4.add(new Person());
        list1=list4;
        Person person=list1.get(0);
        System.out.println(person);

        list2=list4;
        Object obj=list2.get(0);
        System.out.println(obj);

        //写入数据：
        //编译不通过
//        list1.add(new Student());

        //编译通过
        list2.add(new Person());
        list2.add(new Student());
    }
}
